package com.yuantu.judiciary.serviceimpl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.yuantu.judiciary.constant.Regulation;
import com.yuantu.judiciary.dao.*;
import com.yuantu.judiciary.exception.enums.*;
import com.yuantu.judiciary.model.domain.*;
import com.yuantu.judiciary.model.dto.AuthorizedInfoDTO;
import com.yuantu.judiciary.model.dto.EntBasicDTO;
import com.yuantu.judiciary.model.dto.MySearchPageDTO;
import com.yuantu.judiciary.model.dto.SearchRecordContentDTO;
import com.yuantu.judiciary.model.enums.*;
import com.yuantu.judiciary.model.form.AddQueryRecordForm;
import com.yuantu.judiciary.model.form.AddSearchRecordForm;
import com.yuantu.judiciary.model.form.GetQueryInfoForm;
import com.yuantu.judiciary.model.vo.*;
import com.yuantu.judiciary.service.*;
import com.yuantu.judiciary.utils.AssertUtil;
import com.yuantu.judiciary.utils.StringUtil;
import com.yuantu.judiciary.utils.TimeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 查询记录接口实现
 *
 * @author syw
 * @since 2023-07-06
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class QueryRecordServiceImpl implements IQueryRecordService {

    private static final Gson GSON = new Gson();
    private final IQueryRecordDao queryRecordDao;
    private final IQueryEntityDao queryEntityDao;
    private final IUserFollowDao userFollowDao;
    private final IAccountDao accountDao;
    private final IUserRelationDao userRelationDao;
    private final ICheckResultService checkResultService;
    private final IOrganizationDao organizationDao;
    private final IUserInfoDao userInfoDao;
    private final IVipOrderRefundDao refundDao;
    private final IVipOrderDao orderDao;
    private final ISearchRecordService searchRecordService;
    private final IOrgVipRecordDao orgVipRecordDao;
    private final ISysFileDao sysFileDao;
    private final ISmsRecordDao smsRecordDao;
    private final IOrganizationSourceDao organizationSourceDao;
    private final IPersonRemoveDao personRemoveDao;


    @Override
    public QueryRecordVO get(Long userId, SearchRecordContentDTO form, SearchType type) {
//        QueryRecordDO queryRecord = queryRecordDao.findByCreatorIdAndTypeAndContentAndDeletedFalse(
//                userId, type, JSON.toJSONString(form)
//        );
//        return ObjectUtils.isEmpty(queryRecord) ? new QueryRecordVO() : new QueryRecordVO(queryRecord.getId(), queryRecord.getAuthorizedResult());
        return new QueryRecordVO();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String getOther(Long userId, SearchRecordContentDTO form, SearchType searchType) {

        AccountDO account = accountDao.findByIdAndDeletedFalse(userId);
        AddSearchRecordForm addSearchRecord = new AddSearchRecordForm();
        addSearchRecord.setContent(form);
        addSearchRecord.setType(SearchType.PERSON);
        searchRecordService.add(account.getId(), addSearchRecord);
        String content = JSON.toJSONString(form);
        Timestamp currentTime = new Timestamp(System.currentTimeMillis());
        QueryRecordDO queryRecord = new QueryRecordDO();
        queryRecord.setCreatorId(userId);
        queryRecord.setContent(content);
        queryRecord.setType(SearchType.PERSON);
        queryRecord.setOrigin(EndpointType.ALIPAY_APPLET.equals(account.getOrigin()) ? EndpointType.ALIPAY_APPLET : EndpointType.APPLET);
        queryRecord.setAuthorizedResult(AuthResultType.AUTHORIZED);
        queryRecord.setAuthorizedTime(currentTime);
        queryRecord.setExpiresTime(new Timestamp(currentTime.getTime() + (7 * 24 * 60 * 60 * 1000)));
        QueryEntityDO entity = new QueryEntityDO(form.getName(), form.getIdNumber(), SearchType.PERSON);
        entity.setCreatorId(userId);
        queryEntityDao.save(entity);
        queryRecord.setEntityId(entity.getId());
        queryRecordDao.save(queryRecord);
        OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
        OrgVipRecordDO orgVipRecord = orgVipRecordDao.findRecordByOrganizationIdAndDeletedFalse(organization.getId());
        orgVipRecord.setTotalSearchTimes(orgVipRecord.getTotalSearchTimes() + 1);
        orgVipRecordDao.save(orgVipRecord);
        return "ok";
    }

    @Override
    public Long getBySelf(Long accountId, SearchType type) {
        AccountDO account = accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);
        UserInfoDO userInfo = userInfoDao.findByIdAndDeletedFalse(account.getUserId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(userInfo), UserExceptionEnum.USER_NOT_EXIST);
        SearchRecordContentDTO form = new SearchRecordContentDTO(userInfo.getUserName(), userInfo.getCertNo(), userInfo.getPhone());
        QueryRecordDO queryRecord = queryRecordDao.findFirstByCreatorIdAndTypeAndAuthorizedResultAndContentAndExpiresTimeGreaterThanEqualAndOriginAndSelfTrueAndDeletedFalseOrderByIdDesc(
                accountId, type, AuthResultType.AUTHORIZED, JSON.toJSONString(form), new Timestamp(System.currentTimeMillis()), EndpointType.ALIPAY_APPLET
        );
        return queryRecord == null ? null : queryRecord.getId();
    }

    @Override
    public PageVO<QueryRecordPersonVO> searchPersonPage(String type, Long userId, Pageable pageable) {
        Page<QueryRecordDO> page = null;
        if (!StringUtils.isNotBlank(type)) {
            page = queryRecordDao.findPageByCreatorIdAndTypeWithExample(userId, SearchType.PERSON, pageable);
        } else {
            if (QueryRecordType.SELF.getKey().equals(type)) {
                page = queryRecordDao.findPageByCreatorIdAndTypeWithExampleForSelf(userId, SearchType.PERSON, pageable, true);
            }
            if (QueryRecordType.OTHER.getKey().equals(type)) {
                page = queryRecordDao.findPageByCreatorIdAndTypeWithExampleForSelf(userId, SearchType.PERSON, pageable, false);
            }
        }
        if (page == null) {
            return new PageVO<>(0L, new ArrayList<>());
        }
        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data -> {
            SearchRecordContentDTO param = JSON.parseObject(data.getContent(), SearchRecordContentDTO.class);
            UserFollowDO follow = userFollowDao.findByEntityIdAndCreatorIdAndDeletedFalse(data.getEntityId(), userId);
            Boolean isRefund = null;
            if (StringUtils.isNotBlank(data.getTradeNo())) {
                VipOrderDO order = orderDao.findOrderByTradeNoAndDeletedFalse(data.getTradeNo());
                if (order != null && "TRADE_SUCCESS".equals(order.getState()) && AuthResultType.AUTHORIZED_EXPIRED.equals(data.getAuthorizedResult())) {
                    String tradeNo = data.getTradeNo();
                    VipOrderRefundDO refund = refundDao.findByTradeNoAndDeletedFalse(tradeNo);
                    if (refund != null) {
                        String refundStatus = refund.getRefundStatus();
                        if ("REFUND_SUCCESS".equals(refundStatus)) {
                            isRefund = true;
                        } else {
                            isRefund = false;
                        }
                    } else {
                        isRefund = false;
                    }
                }
            }
            String idNumber = param.getIdNumber();
            PersonRemoveDO personRemove = personRemoveDao.findInfoByIdNumber(idNumber);
            return new QueryRecordPersonVO(data.getId(), param.getName(), param.getIdNumber(), param.getPhone(),
                    data.getAuthorizedResult(), data.getCreateTime(), !ObjectUtils.isEmpty(follow),
                    AuthResultType.AUTHORIZED.equals(data.getAuthorizedResult()) ? "认证通过" : "认证不通过",
                    data.getLatestDataTime() == null ? data.getCreateTime() : data.getLatestDataTime(), data.getExample(), isRefund, personRemove == null);
        }).collect(Collectors.toList()));
    }

    @Override
    public PageVO<QueryRecordPersonVO> searchPersonPageCondition(Long userId, Pageable pageable, Boolean self) {
        Page<QueryRecordDO> page;
        if (self == null) {
            page = queryRecordDao.findPageByCreatorIdAndType(userId, SearchType.PERSON, pageable);
        } else {
            page = queryRecordDao.findSelfRecords(userId, SearchType.PERSON, pageable, self);
        }
        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data -> {
            SearchRecordContentDTO param = JSON.parseObject(data.getContent(), SearchRecordContentDTO.class);
            UserFollowDO follow = userFollowDao.findByEntityIdAndCreatorIdAndDeletedFalse(data.getEntityId(), userId);
            Boolean isRefund = null;
            if (StringUtils.isNotBlank(data.getTradeNo())) {
                VipOrderDO order = orderDao.findOrderByTradeNoAndDeletedFalse(data.getTradeNo());
                if (order != null && "TRADE_SUCCESS".equals(order.getState()) && AuthResultType.AUTHORIZED_EXPIRED.equals(data.getAuthorizedResult())) {
                    String tradeNo = data.getTradeNo();
                    VipOrderRefundDO refund = refundDao.findByTradeNoAndDeletedFalse(tradeNo);
                    if (refund != null) {
                        String refundStatus = refund.getRefundStatus();
                        if ("REFUND_SUCCESS".equals(refundStatus)) {
                            isRefund = true;
                        } else {
                            isRefund = false;
                        }
                    } else {
                        isRefund = false;
                    }
                }
            }
            return new QueryRecordPersonVO(data.getId(), param.getName(), param.getIdNumber(), param.getPhone(),
                    data.getAuthorizedResult(), data.getCreateTime(), !ObjectUtils.isEmpty(follow),
                    AuthResultType.AUTHORIZED.equals(data.getAuthorizedResult()) ? "认证通过" : "认证不通过",
                    data.getLatestDataTime() == null ? data.getCreateTime() : data.getLatestDataTime(), data.getExample(), isRefund);
        }).collect(Collectors.toList()));
    }

    @Override
    public List<QueryRecordAuthVO> getQueryRecordAuthList(Long accountId, Integer isUpload, String queryType) {

        Long organizationId = accountDao.findByIdAndDeletedFalse(accountId).getOrganizationId();
        List<Long> userIds = accountDao.findAccountByOrganizationIdAndDeletedFalse(organizationId).stream().
                map(AccountDO::getId).collect(Collectors.toList());
        Timestamp now = new Timestamp(System.currentTimeMillis());
        List<QueryRecordAuthVO> result = new ArrayList<>();
        SearchType searchType = SearchType.valueOf(queryType);
        List<QueryRecordDO> queryRecordInfos = queryRecordDao.findInfoByCreatorIdInAndTypeAndIsFileAndIsUploadAndDeletedFalse(userIds,
                searchType, true, isUpload);
        List<Long> queryIds = queryRecordInfos.stream().map(QueryRecordDO::getId).collect(Collectors.toList());
        Map<Long, SysFileDO> fileMap = sysFileDao.findInfosByRelativeIdInAndRelativeTypeInAndDeletedFalse(queryIds,
                Arrays.asList(FileRelativeType.PER_AUTH, FileRelativeType.ENT_AUTH)).stream().collect(Collectors.toMap(SysFileDO::getRelativeId, Function.identity(), (s1, s2) -> s2));
        for (QueryRecordDO queryRecordInfo : queryRecordInfos) {
            QueryRecordAuthVO queryRecordAuth = new QueryRecordAuthVO();
            queryRecordAuth.setId(queryRecordInfo.getId());
            String content = queryRecordInfo.getContent();
            SearchRecordContentDTO searchRecordContent = JSON.parseObject(content, SearchRecordContentDTO.class);
            queryRecordAuth.setName(searchRecordContent.getName());
            queryRecordAuth.setIdNumber(searchRecordContent.getIdNumber());
            queryRecordAuth.setPhone(searchRecordContent.getPhone());
            Timestamp expiresTime = queryRecordInfo.getExpiresTime();
            long diffMillis = expiresTime.getTime() - now.getTime();
            long hours = TimeUnit.HOURS.convert(diffMillis, TimeUnit.MILLISECONDS);
            queryRecordAuth.setLeftHour(hours);
            queryRecordAuth.setExpiresTime(expiresTime);
            SysFileDO sysFile = fileMap.getOrDefault(queryRecordInfo.getId(), new SysFileDO());
            queryRecordAuth.setUploadTime(sysFile.getCreateTime());
            queryRecordAuth.setFileUrl(sysFile.getUrl());
            result.add(queryRecordAuth);
        }
        return result;
    }

    @Override
    public PageVO<QueryDetailVO> searchQueryRecordList(QuerySearchVO querySearch, Pageable pageable) {

        Page<QueryRecordDO> queryPageInfo = queryRecordDao.findQueryInfos(querySearch, pageable);
        List<QueryRecordDO> content = queryPageInfo.getContent();
        if (CollectionUtils.isEmpty(content)) {
            return new PageVO<>(queryPageInfo.getTotalElements(), Collections.emptyList());
        }
        List<Long> userIds = content.stream().map(QueryRecordDO::getCreatorId).distinct().collect(Collectors.toList());
        Map<Long, IAccountDao.AccountUserInfo> userInfoMap = accountDao.getAccountInfo(userIds).stream().
                collect(Collectors.toMap(IAccountDao.AccountUserInfo::getAccountId, Function.identity(), (s1, s2) -> s2));
        List<QueryDetailVO> result = new ArrayList<>();
        for (QueryRecordDO queryRecord : content) {
            QueryDetailVO queryDetail = new QueryDetailVO();
            queryDetail.setQueryId(queryRecord.getId());
            queryDetail.setQuerySource(queryRecord.getOrigin().toString());
            queryDetail.setQueryType(queryRecord.getType().toString());
            queryDetail.setAuthorizeStatus(queryRecord.getAuthorizedResult().toString());
            queryDetail.setIsAuth(queryRecord.getIsFile() != null);
            Long creatorId = queryRecord.getCreatorId();
            IAccountDao.AccountUserInfo accountUserInfo = userInfoMap.get(creatorId);
            if (accountUserInfo != null) {
                queryDetail.setUserName(accountUserInfo.getUsername());
                queryDetail.setQueryPhone(accountUserInfo.getPhone());
            }
            queryDetail.setCreateTime(queryRecord.getCreateTime());
            String queryContent = queryRecord.getContent();
            if (StringUtils.isNotBlank(queryContent)) {
                SearchRecordContentDTO searchRecordContent = JSON.parseObject(queryContent, SearchRecordContentDTO.class);
                queryDetail.setQueryName(searchRecordContent.getName());
                queryDetail.setQueryPhone(searchRecordContent.getPhone());
            }
            result.add(queryDetail);
        }
        return new PageVO<>(queryPageInfo.getTotalElements(), result);
    }

    @Override
    public List<QueryTimeVO> searchQueryTimeInfos(Long queryId) {

        QueryRecordDO queryRecord = queryRecordDao.findByIdAndDeletedFalse(queryId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(queryRecord), QueryRecordExceptionEnum.QUERY_RECORD_NOT_EXIST);
        List<QueryTimeVO> result = new ArrayList<>();
        QueryTimeVO queryTime = new QueryTimeVO();
        queryTime.setContent("查询发起时间");
        queryTime.setHappenTime(queryRecord.getCreateTime());
        result.add(queryTime);
        String tradeNo = queryRecord.getTradeNo();
        if (!StringUtil.isEmpty(tradeNo)) {
            VipOrderDO order = orderDao.findOrderByTradeNoAndDeletedFalse(tradeNo);
            if (order != null && order.getPayState() == PayState.SUCCESS) {
                QueryTimeVO payTime = new QueryTimeVO();
                payTime.setContent("支付成功时间");
                payTime.setHappenTime(order.getPayTime());
                result.add(payTime);
            }
        }
        Long creatorId = queryRecord.getCreatorId();
        AccountDO account = accountDao.findByIdAndDeletedFalse(creatorId);
        String content = queryRecord.getContent();
        SearchRecordContentDTO searchRecordContent = JSON.parseObject(content, SearchRecordContentDTO.class);
        OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
        String company = organization != null && OrganizationType.ENTER.equals(organization.getType()) ? organization.getEnterName() : account.getUsername();
        String smsContent = JSON.toJSONString(new AuthorizedInfoDTO(queryId, searchRecordContent.getName(),
                searchRecordContent.getIdNumber(), searchRecordContent.getPhone(), company, AuthType.QUERY));
        List<SmsRecordDO> smsRecords = smsRecordDao.findByContentAndTypeAndDeletedFalse(smsContent, SmsTemplateType.AUTHORIZED);
        if (!CollectionUtils.isEmpty(smsRecords)) {
            SmsRecordDO smsRecord = smsRecords.stream().max(Comparator.comparing(SmsRecordDO::getCreateTime)).get();
            QueryTimeVO smsTime = new QueryTimeVO();
            smsTime.setContent("短信发送时间");
            smsTime.setHappenTime(smsRecord.getCreateTime());
            result.add(smsTime);
        }
        AuthResultType authorizedResult = queryRecord.getAuthorizedResult();
        if (authorizedResult == AuthResultType.AUTHORIZED) {
            SearchType type = queryRecord.getType();
            FileRelativeType fileRelativeType = type == SearchType.ENTERPRISE ? FileRelativeType.ENT_AUTH : FileRelativeType.PER_AUTH;
            List<SysFileDO> fileInfos = sysFileDao.findInfosByRelativeIdInAndRelativeTypeInAndDeletedFalse(Collections.
                    singletonList(queryId), Collections.singletonList(fileRelativeType));
            if (!CollectionUtils.isEmpty(fileInfos)) {
                SysFileDO sysFile = fileInfos.stream().max(Comparator.comparing(SysFileDO::getCreateTime)).get();
                QueryTimeVO authFileTime = new QueryTimeVO();
                authFileTime.setContent("授权文件上传时间");
                authFileTime.setHappenTime(sysFile.getCreateTime());
                result.add(authFileTime);
            }
            QueryTimeVO authTime = new QueryTimeVO();
            authTime.setContent("授权成功时间");
            authTime.setHappenTime(queryRecord.getAuthorizedTime());
            result.add(authTime);
        }
        return result;
    }

    @Override
    public PageVO<QuerySourceVO> searchQueryRecordAuthList(QuerySourceSearchVO search, Pageable pageable) {

        Page<QueryRecordDO> queryPageInfo = queryRecordDao.findQueryAuthInfos(search, pageable);
        List<QueryRecordDO> content = queryPageInfo.getContent();
        if (CollectionUtils.isEmpty(content)) {
            return new PageVO<>(queryPageInfo.getTotalElements(), Collections.emptyList());
        }
        List<Long> queryIds = content.stream().map(QueryRecordDO::getId).collect(Collectors.toList());
        Map<Long, SysFileDO> fileMap = sysFileDao.findInfosByRelativeIdInAndRelativeTypeInAndDeletedFalse(queryIds,
                Arrays.asList(FileRelativeType.ENT_AUTH, FileRelativeType.PER_AUTH)).stream().collect(Collectors.
                toMap(SysFileDO::getRelativeId, Function.identity(), (k, v) -> v));
        List<Long> creatorIds = content.stream().map(QueryRecordDO::getCreatorId).collect(Collectors.toList());
        List<IAccountDao.AccountUserInfo> accountInfos = accountDao.getAccountInfo(creatorIds);
        Map<Long, IAccountDao.AccountUserInfo> userInfoMap = accountInfos.stream().collect(Collectors.toMap(IAccountDao.
                AccountUserInfo::getAccountId, Function.identity(), (k, v) -> v));
        List<Long> organizationIds = accountInfos.stream().map(IAccountDao.AccountUserInfo::getOrganizationId).collect(Collectors.toList());
        Map<Long, OrganizationDO> orgMap = organizationDao.findByIdInAndDeletedFalse(organizationIds).stream().
                collect(Collectors.toMap(OrganizationDO::getId, Function.identity(), (k, v) -> v));
        Map<Long, OrganizationSourceDO> orgSourceMap = organizationSourceDao.findAllInfos().stream().collect(Collectors.
                toMap(OrganizationSourceDO::getId, Function.identity(), (k, v) -> v));
        List<QuerySourceVO> result = new ArrayList<>();
        for (QueryRecordDO queryRecord : content) {
            QuerySourceVO querySource = new QuerySourceVO();
            querySource.setQueryId(queryRecord.getId());
            querySource.setQueryTime(queryRecord.getCreateTime());
            querySource.setExpireTime(queryRecord.getExpiresTime());
            querySource.setQueryType(queryRecord.getType().name());
            Long id = queryRecord.getId();
            SysFileDO sysFile = fileMap.get(id);
            if (sysFile != null) {
                querySource.setUploadStatus(1);
                querySource.setFileUrl(sysFile.getUrl());
            } else {
                querySource.setUploadStatus(0);
            }
            Long creatorId = queryRecord.getCreatorId();
            IAccountDao.AccountUserInfo userInfo = userInfoMap.get(creatorId);
            if (userInfo != null) {
                Long organizationId = userInfo.getOrganizationId();
                OrganizationDO organization = orgMap.getOrDefault(organizationId, new OrganizationDO());
                querySource.setOrgName(organization.getEnterName());
                querySource.setOrgSource(orgSourceMap.getOrDefault(organization.getOrganizationSourceId(), new OrganizationSourceDO()).getOrgSource());
            }
            result.add(querySource);
        }
        return new PageVO<>(queryPageInfo.getTotalElements(), result);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean addQueryRecordAuth(Long queryId) {
        Timestamp expireTime = new Timestamp(System.currentTimeMillis() + (48 * 60 * 60 * 1000));
        queryRecordDao.updateQueryRecordAuth(queryId, expireTime);
        return true;
    }

    @Override
    public PageVO<QueryRecordEnterpriseVO> searchEnterprisePage(Long userId, Pageable pageable) {
        Page<QueryRecordDO> page = queryRecordDao.findPageByCreatorIdAndTypeWithExample(userId, SearchType.ENTERPRISE, pageable);
        if (CollectionUtils.isEmpty(page.getContent())) {
            return new PageVO<>(page.getTotalElements(), Collections.emptyList());
        }

        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data -> {
            SearchRecordContentDTO param = JSON.parseObject(data.getContent(), SearchRecordContentDTO.class);

            QueryEntityDO entity;
            if (ObjectUtils.isEmpty(data.getEntityId())) {
                entity = queryEntityDao.findByNameAndCodeAndTypeAndCreatorIdAndDeletedFalse(param.getName(), "", SearchType.ENTERPRISE, userId);
            } else {
                entity = queryEntityDao.findByIdAndDeletedFalse(data.getEntityId());
            }
            if (ObjectUtils.isEmpty(entity)) {
                entity = new QueryEntityDO(param.getName(), "", SearchType.ENTERPRISE);
                entity.setCreatorId(userId);
                queryEntityDao.save(entity);
            }
            if (ObjectUtils.isEmpty(data.getEntityId()) || !data.getEntityId().equals(entity.getId())) {
                data.setEntityId(entity.getId());
                queryRecordDao.save(data);
            }

            QueryRecordEnterpriseVO res = new QueryRecordEnterpriseVO();
            res.setId(data.getId());
            res.setEnterpriseName(param.getName());
            res.setQueryResult(data.getAuthorizedResult());
            res.setCreateTime(data.getCreateTime());
            UserFollowDO follow = userFollowDao.findByEntityIdAndCreatorIdAndDeletedFalse(data.getEntityId(), userId);
            res.setIsFollow(!ObjectUtils.isEmpty(follow));
            res.setLatestDataTime(data.getLatestDataTime() == null ? data.getCreateTime() : data.getLatestDataTime());
            res.setIsExample(data.getExample());
            Map<UserRelationType, Set<Long>> userRelationMap = userRelationDao.findByCreatorIdAndDeletedFalse(userId).stream()
                    .collect(Collectors.groupingBy(UserRelationDO::getType, Collectors.mapping(UserRelationDO::getEntityId, Collectors.toSet())));
            res.setIsCustomer(userRelationMap.getOrDefault(UserRelationType.CUSTOMER, Collections.emptySet()).contains(data.getEntityId()));
            res.setIsSupplier(userRelationMap.getOrDefault(UserRelationType.SUPPLIER, Collections.emptySet()).contains(data.getEntityId()));
            if (AuthResultType.AUTHORIZED.equals(data.getAuthorizedResult())) {
                log.info("查询实体信息为:{}", JSON.toJSONString(entity));
                String companyInfoStr = checkResultService.getJsonDataProd(userId, QueryType.ENT_BASIC, param, entity);
                log.info("获取的公司信息 companyInfoStr:{}", companyInfoStr);
                if (!StringUtil.isEmpty(companyInfoStr)) {
                    JsonObject totalInfo = GSON.fromJson(companyInfoStr, JsonObject.class);
                    if (!ObjectUtils.isEmpty(totalInfo)) {
                        EntBasicDTO basic = JSON.parseObject(totalInfo.get("BASIC").toString(), EntBasicDTO.class);
                        res.setOldName(basic.getENTNAME_OLD());
                        res.setType(basic.getENTTYPE());
                        res.setStatus(basic.getENTSTATUS());
                        res.setName(basic.getFRNAME());
                        res.setEsDate(basic.getESDATE());
                        res.setRegCap(basic.getREGCAP());
                    }
                }
            }
            return res;
        }).collect(Collectors.toList()));
    }

    @Override
    public List<MySearchPageVO> getMySearchPage(Long userId, SearchType type, String queryType) {
//        AccountDO account = accountDao.findByIdAndDeletedFalse(userId);
//        List<QueryRecordDO> data = new ArrayList<>();
//        if (StringUtils.isBlank(queryType)) {
//            if (UserType.PRIMARY.equals(account.getType())) {
//                OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
//                AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
//                List<AccountDO> orgAccounts = accountDao.findAccountByOrganizationIdAndDeletedFalse(organization.getId());
//                data = queryRecordDao.findByCreatorIdInAndTypeAndDeletedFalseAndExampleFalse(
//                        orgAccounts.stream().map(AccountDO::getId).collect(Collectors.toSet()), type
//                );
//            } else {
//                data = queryRecordDao.findByCreatorIdAndTypeAndDeletedFalseAndExampleFalse(userId, type);
//            }
//        } else {
//            if (QueryRecordType.SELF.getKey().equals(queryType)) {
//                if (UserType.PRIMARY.equals(account.getType())) {
//                    OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
//                    AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
//                    List<AccountDO> orgAccounts = accountDao.findAccountByOrganizationIdAndDeletedFalse(organization.getId());
//                    data = queryRecordDao.findByCreatorIdInAndTypeAndSelfAndDeletedFalseAndExampleFalse(
//                            orgAccounts.stream().map(AccountDO::getId).collect(Collectors.toSet()), type, true
//                    );
//                } else {
//                    data = queryRecordDao.findByCreatorIdAndTypeAndSelfAndDeletedFalseAndExampleFalse(userId, type, true);
//                }
//            }
//            if (QueryRecordType.OTHER.getKey().equals(queryType)) {
//                if (UserType.PRIMARY.equals(account.getType())) {
//                    OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
//                    AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
//                    List<AccountDO> orgAccounts = accountDao.findAccountByOrganizationIdAndDeletedFalse(organization.getId());
//                    data = queryRecordDao.findByCreatorIdInAndTypeAndSelfAndDeletedFalseAndExampleFalse(
//                            orgAccounts.stream().map(AccountDO::getId).collect(Collectors.toSet()), type, false
//                    );
//                } else {
//                    data = queryRecordDao.findByCreatorIdAndTypeAndSelfAndDeletedFalseAndExampleFalse(userId, type, false);
//                }
//            }
//        }
//
//        data = data.stream().filter(f -> !EndpointType.ALIPAY_APPLET.equals(f.getOrigin())).collect(Collectors.toList());
////        List<QueryRecordDO> data = queryRecordDao.findByCreatorIdAndTypeAndDeletedFalseAndExampleFalse(userId, type);
//        if (CollectionUtils.isEmpty(data)) {
//            return Collections.emptyList();
//        }
//        return data.stream().collect(Collectors.groupingBy(item ->
//                TimeUtil.transferTimeString(item.getCreateTime(), Regulation.YEAR_MONTH_DAY))
//        ).entrySet().stream().map(item -> {
//            MySearchPageVO res = new MySearchPageVO();
//            res.setTime(TimeUtil.transferTime(item.getKey(), Regulation.YEAR_MONTH_DAY));
//            res.setData(item.getValue().stream().map(m -> {
//                SearchRecordContentDTO content = JSON.parseObject(m.getContent(), SearchRecordContentDTO.class);
//                return new MySearchPageDTO(m.getId(), content.getName(), content.getIdNumber(), content.getPhone(), m.getAuthorizedResult());
//            }).sorted(Comparator.comparing(MySearchPageDTO::getId).reversed()).collect(Collectors.toList()));
//            return res;
//        }).sorted(Comparator.comparing(MySearchPageVO::getTime).reversed()).collect(Collectors.toList());


        AccountDO account = accountDao.findByIdAndDeletedFalse(userId);
        List<QueryRecordDO> data = new ArrayList<>();
        if (!StringUtils.isNotBlank(queryType)) {
//            if (UserType.PRIMARY.equals(account.getType())) {
//                OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
//                AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
//                List<AccountDO> orgAccounts = accountDao.findAccountByOrganizationIdAndDeletedFalse(organization.getId());
//                data = queryRecordDao.findByCreatorIdInAndTypeAndDeletedFalseAndExampleFalse(
//                        orgAccounts.stream().map(AccountDO::getId).collect(Collectors.toSet()), type
//                );
//            } else {
            data = queryRecordDao.findByCreatorIdAndTypeAndDeletedFalseAndExampleFalse(userId, type);
            //      }
        } else {
            if (QueryRecordType.SELF.getKey().equals(queryType)) {
//                if (UserType.PRIMARY.equals(account.getType())) {
//                    OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
//                    AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
//                    List<AccountDO> orgAccounts = accountDao.findAccountByOrganizationIdAndDeletedFalse(organization.getId());
//                    data = queryRecordDao.findByCreatorIdInAndTypeAndSelfAndDeletedFalseAndExampleFalse(
//                            orgAccounts.stream().map(AccountDO::getId).collect(Collectors.toSet()), type, true
//                    );
//                } else {
                data = queryRecordDao.findByCreatorIdAndTypeAndSelfAndDeletedFalseAndExampleFalse(userId, type, true);
                //               }
            }
            if (QueryRecordType.OTHER.getKey().equals(queryType)) {
                //微信小程序的逻辑主号能看到所有的账号，现在需要修改为各自看各自的搜索记录
//                if (UserType.PRIMARY.equals(account.getType())) {
//                    OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
//                    AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
//                    List<AccountDO> orgAccounts = accountDao.findAccountByOrganizationIdAndDeletedFalse(organization.getId());
//                    data = queryRecordDao.findByCreatorIdInAndTypeAndSelfAndDeletedFalseAndExampleFalse(
//                            orgAccounts.stream().map(AccountDO::getId).collect(Collectors.toSet()), type, false
//                    );
//                } else {
                data = queryRecordDao.findByCreatorIdAndTypeAndSelfAndDeletedFalseAndExampleFalse(userId, type, false);
                //}
            }
        }

        data = data.stream().filter(f -> !EndpointType.ALIPAY_APPLET.equals(f.getOrigin())).collect(Collectors.toList());
//        List<QueryRecordDO> data = queryRecordDao.findByCreatorIdAndTypeAndDeletedFalseAndExampleFalse(userId, type);
        if (CollectionUtils.isEmpty(data)) {
            return Collections.emptyList();
        }
        return data.stream().collect(Collectors.groupingBy(item ->
                TimeUtil.transferTimeString(item.getCreateTime(), Regulation.YEAR_MONTH_DAY))
        ).entrySet().stream().map(item -> {
            MySearchPageVO res = new MySearchPageVO();
            res.setTime(TimeUtil.transferTime(item.getKey(), Regulation.YEAR_MONTH_DAY));
            res.setData(item.getValue().stream().map(m -> {
                SearchRecordContentDTO content = JSON.parseObject(m.getContent(), SearchRecordContentDTO.class);
                return new MySearchPageDTO(m.getId(), content.getName(), content.getIdNumber(), content.getPhone(), m.getAuthorizedResult());
            }).sorted(Comparator.comparing(MySearchPageDTO::getId).reversed()).collect(Collectors.toList()));
            return res;
        }).sorted(Comparator.comparing(MySearchPageVO::getTime).reversed()).collect(Collectors.toList());
    }

    @Override
    public Boolean getLatestData(Long userId, GetQueryInfoForm form) {
        QueryRecordDO queryRecord = queryRecordDao.findByIdAndDeletedFalse(form.getId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(queryRecord), CheckPersonExceptionEnum.QUERY_RECORD_NOT_EXIST);
        AssertUtil.assertTrue(AuthResultType.AUTHORIZED.equals(queryRecord.getAuthorizedResult()), CheckPersonExceptionEnum.QUERY_AUTHORIZATION_NOT_PASS);

        queryRecord.setLatestDataTime(new Timestamp(System.currentTimeMillis()));
        queryRecordDao.save(queryRecord);

        SearchRecordContentDTO searchRecord = JSON.parseObject(queryRecord.getContent(), SearchRecordContentDTO.class);
        if (SearchType.PERSON.equals(queryRecord.getType())) {
            checkResultService.updateJsonDataProd(userId, QueryType.PER_BAD_RECORD, searchRecord, queryRecord.getEntityId());
            checkResultService.updateJsonDataProd(userId, QueryType.PER_JUDICIAL, searchRecord, queryRecord.getEntityId());
        } else if (SearchType.ENTERPRISE.equals(queryRecord.getType())) {
            checkResultService.updateJsonDataProd(userId, QueryType.ENT_BASIC, searchRecord, queryRecord.getEntityId());
            checkResultService.updateJsonDataProd(userId, QueryType.ENT_JUDICIAL, searchRecord, queryRecord.getEntityId());
        }
        return true;
    }

    @Override
    public PageVO<QueryRecordInfoVO> getList(Long accountId, Pageable pageable) {
        AccountDO account = accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);

        Page<QueryRecordDO> page = queryRecordDao.findPageByCreatorIdAndAuthorizedResultAndDeletedFalseAndTradeNoIsNull(accountId, AuthResultType.AUTHORIZED, pageable);
        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data -> {
            QueryRecordInfoVO res = new QueryRecordInfoVO();
            res.setId(data.getId());
            res.setCreateTime(data.getCreateTime());
            res.setType(data.getType());
            String content = StringUtils.isNotBlank(data.getContent()) ? JSON.parseObject(data.getContent(), SearchRecordContentDTO.class).getName() : "";
            res.setContent(content);
            res.setUsername(account.getUsername());
            return res;
        }).sorted(Comparator.comparing(QueryRecordInfoVO::getCreateTime).reversed()).collect(Collectors.toList()));
    }

    @Override
    public Boolean addRecordByShare(AddQueryRecordForm form) {
        AccountDO account = accountDao.findByOpenIdAndDeletedFalse(form.getSign());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);

        SearchRecordContentDTO searchRecord = new SearchRecordContentDTO(form.getUsername(), form.getIdNumber(), "");
        String content = JSON.toJSONString(searchRecord);
        // 判断用户是否已经提交过，已经提交则不重复添加
        QueryRecordDO verifyExist = queryRecordDao.findByCreatorIdAndTypeAndContentAndDeletedFalse(
                account.getId(), form.getType(), content
        );
        if (!ObjectUtils.isEmpty(verifyExist)) {
            return true;
        }
        QueryRecordDO queryRecord = new QueryRecordDO();
        queryRecord.setCreatorId(account.getId());
        queryRecord.setContent(content);
        queryRecord.setType(form.getType());
        queryRecord.setAuthorizedResult(AuthResultType.AUTHORIZED);
        queryRecord.setAuthorizedTime(new Timestamp(System.currentTimeMillis()));
        queryRecordDao.save(queryRecord);
        return true;
    }

    @Override
    public List<LatestQueryVO> getLatestQueryVO(Long accountId, SearchType searchType, Boolean self) {
        AccountDO account = accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);
        List<Long> accountList = new ArrayList<>();
        accountList.add(accountId);
        Pageable pageable = PageRequest.of(0, 3);
        List<QueryRecordDO> recordDOList = queryRecordDao.findRecords(accountList, searchType, self, pageable);
        List<LatestQueryVO> list = new ArrayList<>();
        recordDOList.forEach(queryRecordDO -> {
            LatestQueryVO latestQueryVO = new LatestQueryVO();
            latestQueryVO.setId(queryRecordDO.getId());
            String content = queryRecordDO.getContent();
            SearchRecordContentDTO recordContent = JSON.parseObject(content, SearchRecordContentDTO.class);
            latestQueryVO.setIdNumber(recordContent.getIdNumber());
            if (self) {
                latestQueryVO.setName(TimeUtil.transferTimeString(queryRecordDO.getCreateTime(), "yyyy-MM-dd"));
            } else {
                String name = JSONObject.parseObject(queryRecordDO.getContent()).getString("name");
                latestQueryVO.setName(name);
            }
            list.add(latestQueryVO);
        });
        return list;
    }
}
